Umiesz już zapisywać commity, ale nadal całe repozytorium znajduje się na Twoim dysku. Zajmiemy się teraz założeniem zdalnego repozytorium i synchronizacją pomiędzy repozytorium zdalnym i lokalnym.
Github, Gitlab, Bitbucket
Repozytorium zdalne musimy założyć na serwerze i często firmy developerskie mają własne serwery wspierające Gita. Istnieją również platformy, które udostępniają — za darmo lub odpłatnie — zdalne repozytoria Gita na swoich serwerach. Do najpopularniejszych z nich należą GitHub, GitLab oraz BitBucket.
W naszym kursie będziemy wykorzystywać GitHuba. Pozostałe serwisy działają na bardzo podobnych zasadach, więc przesiadka na któryś z nich w przyszłości, jeżeli zajdzie taka konieczność, nie powinna sprawić Ci problemu.
GitHub oferuje publiczne i prywatne repozytoria. W trakcie kursu będziemy tworzyć repozytoria publiczne, aby umożliwić Mentorowi bezproblemowe zajrzenie do plików Twoich projektów. Po kursie, tworząc np. projekty komercyjne, śmiało możesz używać repozytoriów prywatnych.
Konfiguracja: klucze SSH
Zanim przejdziemy do nauki obsługi repozytoriów zdalnych, poświęcimy chwilę na konfigurację, dzięki czemu znacznie ułatwimy sobie pracę.
Publiczne repozytorium oznacza, że jest dostępne dla każdego, ale tylko do odczytu. Aby zapisywać commity do zdalnego repozytorium, nadal będziemy musieli przechodzić autoryzację, np. za pomocą podania hasła. W praktyce będziemy się łączyć ze zdalnym repozytorium wielokrotnie w ciągu projektu (a nierzadko też w ciągu jednego dnia), więc wpisywanie hasła za każdym razem byłoby uciążliwe.
Tu z pomocą przychodzą nam klucze SSH. Są to specjalnie wygenerowane ciągi znaków, które będą zapisane w dwóch plikach:
- id_rsa.pub — w tym pliku będzie znajdował się klucz publiczny,
- id_rsa — w tym pliku znajdziesz swój klucz prywatny.
W wielkim skrócie, klucz publiczny można udostępniać każdemu, ponieważ służy on wyłącznie do zaszyfrowania jakiegoś tekstu. Natomiast klucz prywatny musi być zachowany w tajemnicy, ponieważ pozwala on na odszyfrowanie zaszyfrowanego tekstu.
Metafora – klucze SSH
Wyobraź sobie, że prowadzisz wypożyczalnię rowerów. Do każdego roweru dołączasz zapięcie, ale w momencie wypożyczenia jest ono rozpięte i Twój klient nie ma do niego kluczyka. To zapięcie to Twój klucz publiczny. Klient może zwrócić rower o każdej porze, przypinając go do stojaka przed Twoją wypożyczalnią. Rano używasz swojego kluczyka do odpięcia zwróconych rowerów. Ten kluczyk to Twój klucz prywatny.
Tylko Ty masz dostęp do kluczyka, więc nikt oprócz Ciebie nie będzie w stanie odpiąć rowerów — nawet klient, który przed chwilą przypiął rower do stojaka, nie może go ponownie odpiąć.
Tej technologii używa się m.in. do szyfrowania maili, ale Git, korzystając z komunikacji poprzez protokół SSH, będzie ich używał do autoryzacji, czyli zastąpi konieczność wpisywania hasła.
Zajmiemy się teraz wygenerowaniem Twoich kluczy SSH.
Sprawdzenie, czy klucze SSH już istnieją
Zanim przejdziemy dalej, upewnij się, że nie masz już wygenerowanych kluczy SSH. W przeciwnym wypadku istniejące klucze zostaną nadpisane nowymi.
Co prawda można mieć jednocześnie kilka zestawów kluczy, ale wymaga to dodatkowej konfiguracji. Zwykle wystarczy jeden zestaw kluczy dla danego konta użytkownika na komputerze.
Jeśli nie wiesz, czy posiadasz już wygenerowane klucze, możesz to sprawdzić, wpisując w terminalu komendę:
ls -al ~/.ssh
Nie masz wygenerowanych kluczy, jeśli:
- wyświetli się błąd (np. "file does not exists"), lub
- wyświetli się informacja o pustym katalogu, tzn. jedyne pliki, jakie zostaną wyświetlone to "." i ".." (czyli kropka i dwie kropki)
Masz wygenerowane klucze, jeśli powyższa komenda pokaże Ci jakikolwiek plik z rozszerzeniem .pub oraz drugi plik o tej samej nazwie, ale bez rozszerzenia, np. id_rsa.pub i id_rsa.
Jeśli udało Ci się znaleźć wspomniane pliki, nie musisz generować nowych kluczy. Przejdź od razu do podrozdziału "Konfiguracja kluczy SSH w GitHubie".
Generowanie kluczy SSH
Teraz w kilku krokach wyjaśnimy, jak wygenerować klucze SSH.
Krok 1
Najpierw otwórz terminal i wykonaj poniższą komendę, pamiętając, aby zamienić przykładowy adres na swój email:
ssh-keygen -t rsa -b 4096 -C "adres@example.com"
Proszę nie regulować odbiorników ;)
Na poniższych ilustracjach zostały ukryte dane prywatne, takie jak adres email, nazwa użytkownika i szczegółowe informacje dotyczące klucza prywatnego.
Pamiętaj, aby nie publikować tego rodzaju informacji również na swój temat. Nawet jeśli informacje z pojedynczego zrzutu ekranu nie stanowią luki bezpieczeństwa, może okazać się, że suma informacji z wielu zrzutów i postów opublikowanych w internecie może w przyszłości okazać się problemem.
W pierwszym pytaniu skrypt prosi nas o podanie, w jakim pliku ma zostać zapisany klucz prywatny (klucz publiczny będzie pod tą samą ścieżką, ale z rozszerzeniem .pub). Możemy śmiało wcisnąć enter, aby potwierdzić domyślną lokalizację, podaną w nawiasie.
Krok 2
W kolejnym kroku jesteśmy proszeni o podanie hasła do naszego klucza prywatnego. Na potrzeby tego kursu możemy śmiało wcisnąć enter, aby zatwierdzić puste hasło.
Po co hasło do klucza prywatnego?
Hasło do klucza prywatnego jest dodatkową warstwą zabezpieczenia. Dzięki temu, nawet gdyby ktoś zdobył Twój klucz prywatny (np. poprzez kradzież komputera), nie będzie mógł używać Twojego klucza prywatnego do zalogowania się na serwerze (np. korzystania z GitHuba bez hasła) czy odszyfrowania Twoich danych zaszyfrowanych tym kluczem.
W przypadku użycia hasła do klucza będzie trzeba raz wprowadzić hasło. Będzie ono zapamiętane aż do czasu wyłączenia lub restartu komputera. Są różne metody zapamiętywania hasła do klucza w ten sposób, np. komenda ssh-add, o której znajdziesz więcej informacji np. pod tym linkiem.
Gorąco zachęcamy do stworzenia klucza z hasłem, ale biorąc pod uwagę przystępność dla osób z mniejszym doświadczeniem w obsłudze terminala, zakładamy, że klucz zostanie stworzony bez hasła.
Krok 3
Następny krok to potwierdzenie hasła — jeśli w poprzednim kroku nie było podane żadne hasło, tutaj też niczego nie wpisujemy i wciskamy enter.
Był to ostatni krok, po którym wyświetlane są informacje dotyczące stworzonych kluczy. Zwróć szczególną uwagę na linię zaczynającą się od "Your public key has been saved in" - w tej linii podana jest lokalizacja pliku z Twoim kluczem publicznym.
Konfiguracja kluczy SSH w GitHubie
Przejdź teraz na stronę GitHuba. Jeśli masz już konto w tym serwisie, zaloguj się. W przeciwnym razie załóż konto teraz, podając nazwę użytkownika (będzie się wyświetlać przy Twoich projektach), adres email oraz hasło.
Po zalogowaniu zobaczysz swój panel GitHub. Kliknij ikonę użytkownika po prawej stronie, a następnie wybierz Ustawienia:
Nie przejmuj się, jeśli Twoja strona wygląda inaczej niż powyższa ilustracja - dla nowych kont wyświetlana jest inna zawartość.
Na stronie ustawień kliknij w lewej kolumnie "Klucze SSH i GPG", a potem po prawej stronie, w sekcji "Klucze SSH" kliknij guzik "Dodaj nowy klucz":
Zobaczysz formularz dodawania nowego klucza, z polami na Tytuł i Klucz. W polu Tytuł możesz wpisać co chcesz — to pole służy tylko do rozróżnienia kluczy (do jednego konta można dodać wiele kluczy, np. jeśli używasz tego konta na różnych komputerach). Możesz np. wpisać "Mój klucz".
W pole Klucz musisz wkleić zawartość swojego pliku id_rsa.pub. W tym celu w swoim terminalu wpisz komendę cat ~/.ssh/id_rsa.pub:
Zwróć uwagę, że mówimy tutaj o kluczu publicznym, czyli z rozszerzeniem .pub – tylko ten klucz możesz gdziekolwiek podać. Rozpoznasz go po tym, że jego treść zaczyna się od tekstu ssh-rsa, a kończy się Twoim adresem email.
Przypomnienie
Pamiętaj, że zarówno klucz publiczny (id_rsa.pub), jak i prywatny (id_rsa) muszą pozostać w katalogu .ssh. Jeśli którykolwiek z nich usuniesz lub przeniesiesz w inne miejsce na dysku, klucze nie będą działać.
Po wyświetleniu klucza w terminalu zaznacz go za pomocą myszki, a następnie skopiuj (ctrl+shift+c). Wklej go w ustawieniach GitHuba w polu Klucz, a następnie zatwierdź guzikiem "Dodaj klucz SSH":
I to wszystko — klucz SSH jest już skonfigurowany i może być wykorzystywany do pracy. Teraz możemy przejść do założenia pierwszego repozytorium na GitHubie
Zakładanie repozytorium na GitHubie
Każdy projekt powinien mieć własne repozytorium. Całe szczęście, ta operacja jest bardzo prosta.
Konfiguracja w panelu GitHuba
Przejdź na stronę główną GitHuba, aby zobaczyć swój panel użytkownika. Kliknij guzik "Rozpocznij projekt", aby założyć nowe repozytorium:
Po kliknięciu guzika pojawi się formularz. Jedynym polem, które musisz wypełnić, jest nazwa tworzonego repozytorium. Nie wypełniaj i nie zaznaczaj pozostałych pól.
Dlaczego nie zaznaczamy pozostałych pól
Aby bezproblemowo zacząć pracę, co najmniej jedno z repozytoriów (lokalnego i zdalnego) musi być puste. Gdybyśmy zaznaczyli którąś z opcji dot. README, .gitignore lub licencji, zostałby automatycznie stworzony pierwszy commit, a więc repozytorium zdalne nie byłoby puste.
W naszym przypadku, kiedy mamy już zmiany w repozytorium lokalnym, nie chcemy, aby w zdalnym pojawił się jakikolwiek automatyczny commit, więc nie zaznaczamy tych opcji.
Po zatwierdzeniu guzikiem "Utwórz repozytorium" wyświetlą się informacje dotyczące sposobów korzystania z repozytorium:
Nie przejmuj się, jeśli nie rozumiesz, o co w tym chodzi — za chwilę wszystkiego się nauczysz. :)
Pod sekcją "Quick setup" znajdują się trzy scenariusze wykorzystania pustego repozytorium. Pierwszy z nich zakłada, że dopiero zaczynasz projekt i nie masz jeszcze lokalnego repozytorium. W rozdziale "Alternatywa do podłączania — klonowanie repozytorium" zajmiemy się tym scenariuszem, ale zamiast komend przedstawionych przez GitHub zaproponujemy Ci inne rozwiązanie.
Drugi scenariusz to podłączenie repozytorium zdalnego do lokalnego, które już istnieje — tym scenariuszem zajmiemy się już za moment.
Trzecia opcja pozwala na zaimportowanie innego zdalnego repozytorium. Jako że jest to rzadziej wykorzystywana opcja, nie będziemy się nią zajmować.
Na razie najważniejsze jest dla nas, aby w pierwszej sekcji ("Quick setup") była zaznaczona opcja SSH. Właśnie po to generowaliśmy i konfigurowaliśmy klucze SSH.
Czego unikać
Najczęstszym problemem nowych użytkowników GitHuba jest sytuacja, w której mają dwa repozytoria — lokalne i zdalne — i w każdym z nich mają już zapisane jakieś commity. Połączenie tych dwóch repozytoriów jest bardzo problematyczne.
Dlatego trzymaj się zasady, że co najmniej jedno z nich powinno być puste (tzn. świeżo założone).
Przejdźmy teraz do drugiego z wymienionych powyżej scenariuszy — mamy już lokalne repozytorium w projekcie i chcemy do niego podłączyć repozytorium zdalne.
Podłączanie repozytorium zdalnego do lokalnego
Otwórz terminal i wejdź do katalogu z zadaniem z poprzedniego submodułu. Sprawdź za pomocą git tree, jak obecnie wygląda historia zmian.
Skopiuj teraz komendę zaczynającą się od git remote add ze strony repozytorium na Githubie:
Pamiętaj, że nie możesz przepisać komendy z powyższej ilustracji — w adresie znajduje się nazwa użytkownika ("kodilla-kursy") oraz nazwa repozytorium ("nauka-gita").
Wklej skopiowaną komendę do swojego terminala (ctrl+shift+v) i zatwierdź klawiszem enter. Następnie sprawdź listę dodanych serwerów za pomocą komendy git remote -v.
Co się tutaj zadziało? Komenda git remote add dodaje do repozytorium lokalnego adres, pod jakim znajduje się repozytorium zdalne. Słowo origin jest nadawaną przez nas nazwą dla tego adresu — nadajemy nazwę dlatego, że jedno repozytorium lokalne może być synchronizowane z wieloma repozytoriami zdalnymi. Przyjęło się, że podstawowe repozytorium zdalne nazywa się właśnie origin, ale równie dobrze możesz podać inną nazwę.
Przykład zastosowania
Wyobraź sobie, że jesteś częścią zespołu pracującego nad projektem. Wasz klient sam jest programistą i chce mieć dostęp do repozytorium projektu. Z zespołem ustaliliście jednak, że chcielibyście udostępniać klientowi zmiany dopiero po przetestowaniu, czy wszystko działa poprawnie.
W takiej sytuacji możecie założyć jedno repozytorium zdalne, do którego dostęp ma tylko Wasz zespół (nazwijmy je origin), i drugie z dostępem dla klienta ("client").
Na co dzień, przy bieżącej pracy, synchronizujecie swoje lokalne repozytoria ze zdalnym origin. Raz w tygodniu testujecie cały projekt, naprawiacie ewentualne błędy, i dopiero wtedy synchronizujecie repozytorium lokalne z "client".
Klient będzie widział wszystkie commity, które były dodane w trakcie prac, ale dzięki temu będziecie mieć pewność, że najnowszy commit w repozytorium "client" będzie zawsze poprawnie działającym projektem.
Komenda git remote -v wyświetliła nam dwa razy ten sam adres, ponieważ Git zapisuje sobie osobno adres do pobierania zmian z serwera (ang. "fetch") oraz wysyłania zmian na serwer (ang. "push").
Nasze repozytorium lokalne już zna adres repozytorium zdalnego, ale jeszcze nie zostały wysłane żadne dane. Zrób to za pomocą komendy git push -u origin master. Słowo master już pojawiło się w tym module – master to po prostu nasz główny branch.
Pierwsze połączenie z serwerem
Kiedy pierwszy raz łączysz się z serwerem za pomocą protokołu SSH, wyświetli się prośba o potwierdzenie.
Po wpisaniu słowa "yes" i zatwierdzeniu enterem, to pytanie nie powinno się pojawić ponownie na tym samym komputerze, jeżeli łączysz się z tym samym serwerem (np. GitHubem).
Jest to dodatkowe zabezpieczenie przed sytuacją, w której ktoś podszyłby się pod serwer, z którym próbujesz się połączyć. W związku z tym jest to normalne przy pierwszym połączenia i powinno zwrócić Twoją uwagę tylko, gdyby pojawiło się przy kolejnym połączeniu.
Po wykonaniu komendy wyświetlą się dodatkowe informacje dotyczące przesłanych informacji. Może to zająć krótką chwilę, ale powinien pojawić się z powrotem znak zachęty:
Wszystkie dotychczasowe zmiany z naszego repozytorium zostały wysłane na serwer. Możesz to sprawdzić, odświeżając stronę repozytorium.
Interfejs GitHuba omówimy sobie w kolejnym submodule, ale jeśli masz ochotę, możesz pozwiedzać tę stronę. W szczególności warto zwrócić uwagę na link "Commits" (na ilustracji jest to pierwszy link nad czerwonym paskiem).
Alternatywa do podłączania — klonowanie repozytorium
W naszej sytuacji mieliśmy już lokalne repozytorium z zapisanymi commitami. W pracy spotkasz się jednak częściej z sytuacją, kiedy będziesz dołączać do toczącego się projektu. W takiej sytuacji będzie już istniało repozytorium zdalne z zapisanymi commitami i pojawi się potrzeba sklonowania tego repozytorium.
Będzie Ci też wygodniej przy nowych zadaniach w ramach Bootcampa zakładać od razu repozytorium zdalne i z niego klonować swoje repozytorium lokalne.
Pamiętaj, że stosujemy klonowanie tylko w sytuacji, kiedy istnieje repozytorium zdalne, a nie istnieje lokalne na Twoim komputerze.
Stworzymy teraz nowe repozytorium, które będzie "udawać" repo projektu, do którego dołączasz. Możesz do tego wykorzystać ikonę plusa, która znajduje się w prawym górnym rogu strony:
Tym razem przy zakładaniu repozytorium zaznacz opcję stworzenia pliku README.md, co sprawi, że automatycznie zostanie zapisany pierwszy commit. Dzięki temu zobaczysz, jak działa klonowanie w sytuacji, kiedy w zdalnym repozytorium istnieją już jakieś zmiany.
Po stworzeniu repozytorium skopiuj adres repozytorium zdalnego. W przypadku pustego repozytorium wyświetlał się w podpowiedziach widocznych od razu po stworzeniu repozytorium. Tym razem jednak repozytorium nie jest puste, więc adres znajdziesz po prawej stronie nad listą plików, pod guzikiem "Sklonuj lub pobierz":
Następnie otwórz swój terminal i przejdź do katalogu z projektami. Wykonaj komendę git clone adres-repozytorium, oczywiście zamieniając "adres-repozytorium" na adres skopiowany przed chwilą. Po sklonowaniu repozytorium zostanie utworzony katalog o nazwie takiej samej jak nazwa repozytorium. Wejdź do tego katalogu i wyświetl historię zmian oraz listę plików.
Jak widzisz, za pomocą jednej komendy git clone zostały wykonane operacje stworzenia katalog projektu, zainicjowania repozytorium, dodania adresu zdalnego repozytorium i pobrania zmiany z serwera. Masz teraz na swoim komputerze dokładną kopię zdalnego repozytorium.
Co zrobić w przypadku błędu
Przeczytać komunikat w terminalu. To zdecydowanie najlepszy pierwszy krok.
Częstym błędem na tym etapie jest sytuacja, w której w Twoim katalogu z projektami istnieje już niepusty katalog o takiej samej nazwie jak repozytorium, które klonujesz. W takiej sytuacji należy na końcu komendy dodać (po spacji) nazwę katalogu, do którego ma być skopiowane repozytorium.
Podłączanie repo — podsumowanie
Krótkie przypomnienie metod podłączania zdalnego repozytorium:
Zaczynam nowy projekt, nie mam żadnego repozytorium ani plików:
- Zakładam repozytorium na GitHubie, przy zakładaniu mogę zaznaczyć inne opcje poza tytułem repozytorium.
- Klonuję repozytorium na swój dysk za pomocą komendy
git clone adres-repozytorium.
Mam repozytorium lokalne:
- Zakładam puste repozytorium na GitHubie — przy zakładaniu wypełniam tylko nazwę repozytorium.
- Podłączam adres repozytorium zdalnego do lokalnego za pomocą komendy
git remote add origin adres-repozytorium.
- Wykonuję pierwsze wysłanie commitów do zdalnego repozytorium za pomocą komendy
git push -u origin master.
Nie mam repozytorium lokalnego, ale mam pliki projektu na dysku:
- Mogę zastosować pierwszy sposób, a następnie do katalogu sklonowanego repozytorium przenieść pliki projektu, lub
- mogę zainicjować repozytorium w katalogu tego projektu za pomocą komendy
git init, wykonać pierwszy commit, i dalej postępować wedle drugiego sposobu (czyli "Mam repozytorium lokalne").
Podstawowe komendy Gita
Push, czyli wysyłamy nasze zmiany na zdalne repo
Do wysłania commitów z repozytorium lokalnego do zdalnego służy komenda git push.
Jeśli podłączamy adres repozytorium zdalnego do lokalnego za pomocą komendy git remote add adres-repozytorium, to przy pierwszym użyciu komendy git push musimy dodać flagę -u oraz słowa origin master – komendę w tej formie podaliśmy Ci w poprzednim rozdziale. Pamiętaj jednak, że dotyczy to tylko tej konkretnej sytuacji. W pozostałych przypadkach będziemy używać komendy git push bez żadnych argumentów.
Pull, czyli pobieramy zmiany ze zdalnego repo
Ogólnie rzecz ujmując, komenda git pull jest odwrotnością git push, czyli pobiera zmiany z repozytorium zdalnego do lokalnego. Normalnie ma zastosowanie, kiedy ktoś inny pracuje w tym samym projekcie, ale zasymulujemy tę sytuację, korzystając z interfejsu GitHuba.
Uwaga
Przed rozpoczęciem ćwiczenia, które opisujemy poniżej, wykonaj następujące kroki:
- Wykonaj
git status – jeśli wyświetlą się jakieś zmiany do zapisania, wykonaj git add . && git commit -m "Tytuł commita".
- Wykonaj
git push.
W przeciwnym wypadku mógłby pojawić się tzw. "konflikt", czyli Git mógłby nie poradzić sobie z pogodzeniem zmian z repozytoriów zdalnego i lokalnego.
Jeśli cokolwiek pójdzie nie tak, nie przejmuj się — możesz ponownie sklonować zdalne repozytorium do katalogu o innej nazwie i kontynuować naukę w tym nowym katalogu.
Wejdź na stronę repozytorium, na którym pracowaliśmy w poprzednim rozdziale. Na tej stronie widoczna jest lista plików.
Kliknij którąś z nazw plików, np. index.html, a następnie w ikonę ołówka.
Znajdujesz się teraz w trybie edycji tego pliku — zmień jego treść w dowolny sposób. Następnie na dole strony wypełnij tytuł commita i potwierdź zapisanie guzikiem.
Ponownie zobaczysz podgląd pliku, tym razem już z wprowadzonymi zmianami. Przejdź teraz do swojego terminala i wykonaj komendę git pull, a następnie wyświetl historię zmian.
Jak widzisz, na szczycie listy pojawił się najnowszy commit, wykonany przez interfejs GitHuba. Dzięki temu mogliśmy zaktualizować nasze repozytorium lokalne o commit, który pojawił się na repozytorium zdalnym.
Przetestuj to jeszcze raz samodzielnie, ale tym razem zrób dwa commity za pomocą interfejsu GitHuba, a dopiero potem wykonaj git pull.